﻿using AntdUI;
using BarcodeStandard;
using IniHelp;
using Microsoft.Extensions.Logging.Abstractions;
using QRCoder;
using SerialHelp;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Forms;
using TPMS_ScanComparison.Contrals;
using TPMS_ScanComparison.Control;
using TPMS_ScanComparison.Helper;
using TPMS_ScanComparison.Model;
using TPMS_ScanComparison.Properties;
using TPMS_ScanComparison.Tag;
using TPMS_ScanComparison.Weigh;
using static System.Runtime.CompilerServices.RuntimeHelpers;
using static System.Windows.Forms.AxHost;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static TPMS_ScanComparison.Helper.Simple10000Serial;
using static TPMS_ScanComparison.Helper.SimpleSerial;
using Message = AntdUI.Message;

namespace TPMS_ScanComparison
{
    public partial class FormMain : AntdUI.Window
    {
        private CancellationTokenSource cts = new CancellationTokenSource();
        private Dictionary<string, System.Windows.Forms.Control> pageCache = new Dictionary<string, System.Windows.Forms.Control>();
        #region INI字段
        private static string path2 = System.Environment.CurrentDirectory;
        public static IniFile m_ini = new IniFile(path2 + "\\config.ini");
       
        #endregion
        // 私有静态变量存储当前流水号，初始值为0
        private static int _currentNumber = 0;
        public FormMain()
        {
            Global.ReadIniPara();
            InitializeComponent();
            Load += FormMain_Load;
            label3.Text = $"当前产品:{Global.ProductName}";
            input3.Text = Global.ProductName;
            Client();

            //SqlHelper.Db.DbMaintenance.CreateDatabase();//达梦和Oracle不支持建库
            //SqlHelper.sqliteDb.CodeFirst.InitTables<AutoModel>(); //所有库都支持     
            //SqlHelper.sqliteDb.CodeFirst.InitTables<RecipeModel>(); //所有库都支持     
            //SqlHelper.sqliteDb.CodeFirst.InitTables<ManualModel>(); //所有库都支持     
            //SqlHelper.sqliteDb.CodeFirst.InitTables<MediumModel>(); //所有库都支持     
            //SqlHelper.sqliteDb.CodeFirst.InitTables<OuterModel>(); //所有库都支持     
            // IniTest();

        }
        public void IniTest()
        {
            m_ini.IniWriteValue("Number", "Number", 0);

            m_ini.IniWriteValue("OuterCount", "OuterCount", 10);

            m_ini.IniWriteValue("length", "length", 12);

            var str = m_ini.IniReadInt("locket", "locket");

        }
        private void FormMain_Load(object sender, EventArgs e)
        {
            AntdUI.Config.ShowInWindow = true;
            IniClient();
            Global.读码.serial.sp.DataReceived += 读码_datareceive;
            Global.电源.serial.sp.DataReceived += 电源_datareceive;
            for (int i = 0; i < 3; i++)
            {
                Global.PLC.serial.sendData("05");

                // 可选：添加短暂延迟，避免发送过快
                System.Threading.Thread.Sleep(20); // 10毫秒延迟，可根据需要调整
            }

            Global.PLC.serial.GX_SetM0(false);


            lab_locket.Text = Global.locket.ToString();
            lab_medium.Text = Global.Medium.ToString();
            lab_out.Text = Global.Outer.ToString();
            Global.MediumCount = m_ini.IniReadInt("MediumCount", "MediumCount");
            Global.OuterCount = m_ini.IniReadInt("OuterCount", "OuterCount");

        }
        #region 事件

        private void 读码_datareceive(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                if (Global.读码.serial.sp.IsOpen) //严谨性
                {
                    System.Threading.Thread.Sleep(20);
                    int bytestoread = Global.读码.serial.sp.BytesToRead;
                    if (bytestoread == 0) return;

                    byte[] readBuffer = new byte[Global.读码.serial.sp.ReadBufferSize + 1];
                    int count = Global.读码.serial.sp.Read(readBuffer, 0, Global.读码.serial.sp.ReadBufferSize);
                    string tempreadstr = "";

                    tempreadstr = Encoding.Default.GetString(readBuffer, 0, count);
                    Global.curReadStr = tempreadstr;
                    //              SetTextValue(rtb_dis,"读码:"+tempreadstr);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void 电源_datareceive(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                if (sender != Global.电源.serial.sp) return;
                if (Global.电源.serial.sp.IsOpen) // 严谨性检查
                {
                    System.Threading.Thread.Sleep(20); // 等待数据接收完整
                    int bytestoread = Global.电源.serial.sp.BytesToRead;
                    if (bytestoread == 0) return;

                    byte[] readBuffer = new byte[bytestoread]; // 只分配需要的大小
                    int count = Global.电源.serial.sp.Read(readBuffer, 0, bytestoread);

                    // 将字节数组转换为HEX格式字符串（每个字节用两位十六进制表示，空格分隔）
                    StringBuilder hexBuilder = new StringBuilder();
                    for (int i = 0; i < count; i++)
                    {
                        hexBuilder.AppendFormat("{0:X2} ", readBuffer[i]);
                    }
                    string hexStr = hexBuilder.ToString().TrimEnd(); // 去除末尾空格

                    Global.curCurstr = hexStr; // 存储HEX格式字符串
                                               // SetTextValue(rtb_dis, "读码:" + hexStr); // 显示HEX格式数据
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void btn_back_Click(object sender, EventArgs e)
        {
            BeginInvoke(new Action(() =>
            {
                if (windowBar.Tag is System.Windows.Forms.Control control)
                {
                    Controls.Remove(control);
                }
                label3.Text = $"当前产品:{Global.ProductName}";

                windowBar.ShowBack = false;
                virtualPanel.Visible = true;
                windowBar.SubText = "Overview";
            }));
        }
        private void btn_setting_Click(object sender, EventArgs e)
        {
            OpenPage("SetControl");
        }
        private void btn_data_Click(object sender, EventArgs e)
        {
            OpenPage("DataControl");

        }
        private void btn_recipe_Click(object sender, EventArgs e)
        {
            OpenPage("RecipeControl");
        }
        bool setcolor = false;
        #endregion
        private async void button1_Click(object sender, EventArgs e)
        {
             Global.PLC.serial.GX_SetM0(false);
        }
        public void OpenPage(string id)
        {
            System.Windows.Forms.Control control_add = null;
            // 检查缓存中是否已有该页面
            if (pageCache.TryGetValue(id, out control_add))
            {
                // 页面已存在，直接使用
            }
            else
            {
                // 页面不存在，创建新页面并缓存
                switch (id)
                {
                    case "SetControl":
                        control_add = new SetControl(this);
                        break;
                    case "DataControl":
                        control_add = new DataControl(this);
                        break;
                    case "RecipeControl":
                        control_add = new RecipeControl(this);
                        break;
                        // ...其他控件
                }
                // 将新创建的页面添加到缓存
                if (control_add != null)
                {
                    pageCache.Add(id, control_add);
                }
            }
            if (control_add != null)
            {
                windowBar.SubText = id;
                // 移除当前显示的控件，但不释放，以便下次复用
                if (windowBar.Tag is System.Windows.Forms.Control control)
                {
                    Controls.Remove(control);
                }
                windowBar.Tag = control_add;
                BeginInvoke(new Action(() =>
                {
                    virtualPanel.Visible = false;
                    control_add.Dock = DockStyle.Fill;
                    AutoDpi(control_add);
                    Controls.Add(control_add);
                    control_add.BringToFront();
                    control_add.Focus();
                    windowBar.ShowBack = true;
                }));
            }
        }

        private void IniClient()
        {
            var devices = new[]
            {
        new { Device = Global.PLC, Name = "PLC" },
        //new { Device = Global.产品, Name = "TTL" },
        new { Device = Global.读码, Name = "读码器" },
        new { Device = Global.电源, Name = "电源" }
    };

            // 存储所有打开失败的设备信息
            var failedDevices = new List<string>();

            foreach (var dev in devices)
            {
                try
                {
                    dev.Device.参数赋值(dev.Device);
                    bool isSuccess = dev.Device.serial.Broad_PortInitialize();

                    if (!isSuccess)
                    {
                        // 记录打开失败的设备
                        failedDevices.Add(dev.Name);
                    }

                    // 即时显示当前设备的状态
                    this.Invoke((MethodInvoker)delegate
                    {
                        this.alert.Icon = TType.Success;
                        this.alert.Text = "所有设备连接正常";
                    });
                }
                catch (Exception ex)
                {
                    failedDevices.Add(dev.Name);
                    this.Invoke((MethodInvoker)delegate
                    {
                        this.alert.Icon = TType.Warn;
                        this.alert.Text = $"设备端口打开失败：{dev.Name} - {ex.Message}";
                    });
                }
            }

            // 显示所有打开失败的设备
            if (failedDevices.Count > 0)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    this.alert.Icon = TType.Warn;
                    this.alert.Text = $"以下设备端口打开失败：{string.Join("、", failedDevices)}";
                });
            }

            // 启动后台线程持续检测端口状态（仅检测不重连）
            Task.Run(async () =>
            {
                while (!cts.IsCancellationRequested)
                {
                    var currentFailedDevices = new List<string>();

                    foreach (var dev in devices)
                    {
                        // 仅检查端口是否关闭，不进行重连
                        if (!dev.Device.serial.sp.IsOpen)
                        {
                            currentFailedDevices.Add(dev.Name);
                        }
                    }

                    // 显示当前所有未打开的设备
                    if (currentFailedDevices.Count > 0)
                    {
                        this.Invoke((MethodInvoker)delegate
                        {
                            this.alert.Icon = TType.Warn;
                            this.alert.Text = $"当前未连接的设备：{string.Join("、", currentFailedDevices)}";
                        });
                    }
                    else
                    {
                        this.Invoke((MethodInvoker)delegate
                        {
                            this.alert.Icon = TType.Success;
                            this.alert.Text = "所有设备连接正常";
                        });
                    }

                    // 每3秒检测一次端口状态
                    await Task.Delay(3000);
                }
            });
        }

        public void SuccessTest()
        {
            this.Invoke((Action)(() =>
            {
                this.lab_Result.Text = "The test was successful!";
                this.iconState.State = TType.Success;
                Global.locket++;
                m_ini.IniWriteValue("locket", "locket", Global.locket);
                lab_locket.Text = Global.locket.ToString();

            }));

        }
        public void ErrorTest()
        {
            this.Invoke((Action)(() =>
            {
                iconState.State = TType.Error;
                Global.PLC.serial.GX_SetM2(true);
            }));

        }

        private async void button1_Click_1(object sender, EventArgs e)
        {

            TagTest tag = new TagTest();
            
            //Serial10000Generator.ResetAll();

            SerialGenerator.ResetAll();
        }

        private async void btn_repairOut_Click(object sender, EventArgs e)
        {
          

            TagTest tag = new TagTest();
            string prefix = input1.Text.Trim();
            if (Global.ProductName != "NXP金捷")
            {
                var code = await tag.BuOutCode(prefix);
                if (code == "")
                {
                    lab_Result.Text = "补打外盒失败未找到该码";
                    iconState.State = TType.Error;

                }
                else
                {
                    tag.QrMTAG(code, prefix);
                    await Task.Delay(500);
                    tag.QrMTAG(code, prefix);
                    lab_Result.Text = "补打成功";
                    iconState.State = TType.Success;
                }
            }
            else
            {
                var code = await tag.BuOut128Code(prefix);
                if (code == "")
                {
                    lab_Result.Text = "补打外盒失败未找到该码";
                    iconState.State = TType.Error;

                }
                else
                {
                    tag.BarcodeDataMTAG(prefix, prefix);
                    await Task.Delay(200);
                    tag.BarcodeDataMTAG(prefix, prefix);
                    lab_Result.Text = "补打成功";
                    iconState.State = TType.Success;
                }
            }
          
           

        }

        private async void btn_repairMedium_Click(object sender, EventArgs e)
        {
            TagTest tag = new TagTest();
            string prefix = input2.Text.Trim();
            string CUR = input3.Text.Trim();
            if (Global.ProductName != "NXP金捷")
            {
                var code = await tag.QrgggggCode(CUR, prefix);
                if (code == "")
                {
                    lab_Result.Text = "补打中盒失败未找到该码";
                    iconState.State = TType.Error;

                }
                else
                {
                    tag.QrTAG(code, prefix);
                    lab_Result.Text = "补打成功";
                    iconState.State = TType.Success;
                }
            }
            else 
            {
                var code2 = await tag.Manual128Code(prefix);
                if (code2=="")
                {
                    lab_Result.Text = "补打中盒失败未找到该码";
                    iconState.State = TType.Error;

                }
                else
                {
                    tag.BarcodeMTAG(CUR, CUR);
                    lab_Result.Text = "补打成功";
                    iconState.State = TType.Success;
                }

            }
         
        }



        private void Client()
        {
            WeighTest weighData = new WeighTest();
            TagTest tag = new TagTest();
            string errorMsg = "";
            int lastM0 = 0; // 记录上一次M13的状态
            // 返工模式状态变量
            bool isReworkMode = false;
            string oldBarcodeForReplacement = ""; // 存储需要替换的旧产品条码

            Task.Run(async () =>
            {
                while (!cts.IsCancellationRequested)
                {
                    // 读取配置信息
                    Global.prefix = m_ini.IniReadValue("prefix", "prefix");
                    Global.length = m_ini.IniReadInt("length", "length");
                    Global.ProductName = m_ini.IniReadValue("ProductName", "ProductName");
                    Global.MediumCount = m_ini.IniReadInt("MediumCount", "MediumCount");
                    Global.OuterCount = m_ini.IniReadInt("OuterCount", "OuterCount");
                    string requiredPrefix = Global.prefix; // 要求的条码前缀
                    int requiredLength = Global.length; // 要求的条码总长度（包含前缀）

                    try
                    {
                        int currentM0 = Global.PLC.serial.GX_ReadM0();
                        if (currentM0 == 1 && lastM0 == 0)
                        {
                            // 更新返工模式状态
                            this.Invoke((Action)(() =>
                            {
                                isReworkMode = chk_Rework.Checked;
                            }));

                            lab_Result.Text = "testing...";
                            iconState.State = TType.Info;
                            Global.curReadStr = "";

                            // 第一次扫码（提取重复逻辑）
                            string firstBarcode = await PerformScan();
                            if (string.IsNullOrEmpty(firstBarcode))
                            {
                                throw new Exception("扫码失败");
                            }

                            // 处理返工模式（统一逻辑，支持所有产品）
                            if (isReworkMode)
                            {
                                await ProcessReworkMode(firstBarcode, requiredPrefix, requiredLength, tag);
                            }
                            // 正常生产模式
                            else
                            {
                                // 条码校验（提取重复逻辑）
                                ValidateBarcode(firstBarcode, requiredPrefix, requiredLength);

                                // 根据产品类型处理
                                if (Global.ProductName == "NXP金捷")
                                {
                                    await ProcessNXPProduction(firstBarcode, weighData, tag);
                                }
                                else
                                {
                                    await ProcessOtherProduction(firstBarcode, weighData, tag);
                                }
                            }
                            //Global.PLC.serial.GX_SetM0(false);
                        }

                        lastM0 = currentM0;
                    }
                    catch (Exception ex)
                    {
                        errorMsg = ex.Message;
                        this.Invoke((Action)(() =>
                        {
                            lab_Result.Text = errorMsg;
                        }));
                        ErrorTest();

                        // 错误时重置返工状态
                        if (isReworkMode)
                        {
                            oldBarcodeForReplacement = "";
                        }
                    }

                    await Task.Delay(100);
                }
            });
        }

        #region 通用方法（提取重复逻辑）
        /// <summary>
        /// 执行扫码操作（通用方法）
        /// </summary>
        private async Task<string> PerformScan()
        {
            int waitqty = 0;
            Global.curReadStr = "";
            while (waitqty < 50 && string.IsNullOrEmpty(Global.curReadStr))
            {
                Global.读码.serial.sp.Write("T");
                waitqty++;
                await Task.Delay(100);
            }
            return Global.curReadStr?.Trim();
        }

        /// <summary>
        /// 条码校验（通用方法）
        /// </summary>
        private void ValidateBarcode(string barcode, string requiredPrefix, int requiredLength)
        {
            if (!barcode.StartsWith(requiredPrefix))
            {
                throw new Exception($"校验失败：前缀不符");
            }

            if (barcode.Length != requiredLength)
            {
                throw new Exception($"校验失败：长度不符'{barcode}'");
            }
        }

        /// <summary>
        /// 执行激光烧录（通用方法）
        /// </summary>
        private async Task ExecuteLaserBurn()
        {
            if (this.checkbox1.Checked)
            {
                this.Invoke((Action)(() =>
                {
                    lab_Result.Text = "正在激光";
                }));

                Global.PLC.serial.GX_SetM1(true);

                while (true)
                {
                    int M0 = Global.PLC.serial.GX_ReadM0();
                    if (M0 == 1)
                    {
                        break;
                    }
                    await Task.Delay(100);
                }
            }
            else
            {
                Global.PLC.serial.GX_SetM0(false);
            }
        }

        /// <summary>
        /// 处理返工模式（通用方法，支持所有产品）
        /// </summary>
        private async Task ProcessReworkMode(string firstBarcode, string requiredPrefix, int requiredLength, TagTest tag)
        {
            string oldBarcodeForReplacement = "";

            if (string.IsNullOrEmpty(oldBarcodeForReplacement))
            {
                // 获取旧记录及主键ID（关键：必须获取主键才能正确更新）
                var (oldRecord, recordId, isNXP) = await GetOldRecordWithId(firstBarcode);
                if (oldRecord == null || recordId <= 0)
                {
                    throw new Exception($"未找到需要替换的产品条码或ID无效: {firstBarcode}");
                }

                // 等待扫描新产品条码
                oldBarcodeForReplacement = firstBarcode;
                this.Invoke((Action)(() =>
                {
                    lab_Result.Text = "请扫描新产品条码";
                }));
                await Task.Delay(2000);

                // 第二次扫码
                string secondBarcode = await PerformScan();
                if (string.IsNullOrEmpty(secondBarcode))
                {
                    throw new Exception("第二次扫码失败");
                }

                // 校验新条码
                ValidateBarcode(secondBarcode, requiredPrefix, requiredLength);

                // 检查新条码是否已存在
                if (await IsBarcodeExists(secondBarcode, isNXP))
                {
                    throw new Exception($"新产品条码已存在: {secondBarcode}");
                }

                // 构造包含主键ID的更新实体（符合SugarORM更新规范）
                object updateEntity = null;
                if (isNXP)
                {
                    // 对于NXP产品：创建新实体并设置主键ID和需要更新的字段
                    updateEntity = new AutoModel
                    {
                        Id = recordId,  // 必须指定主键ID
                        case_code = secondBarcode,
                        Whether_rework = true
                    };
                }
                else
                {
                    // 对于其他产品：同样需要指定主键ID
                    updateEntity = new ManualModel
                    {
                        Id = recordId,  // 必须指定主键ID
                        case_code = secondBarcode,
                        Whether_rework = true
                    };
                }

                // 执行更新（SugarORM会根据主键ID定位记录）
                long updateResult = 0;
                if (isNXP)
                {
                    updateResult = await SqlHelper.sqliteDb.Updateable(updateEntity as AutoModel).ExecuteCommandAsync();
                }
                else
                {
                    updateResult = await SqlHelper.sqliteDb.Updateable(updateEntity as ManualModel).ExecuteCommandAsync();
                }

                if (updateResult <= 0)
                {
                    throw new Exception($"更新失败，ID: {recordId} 可能不存在或已被修改");
                }

                // 激光烧录
                await ExecuteLaserBurn();

                this.Invoke((Action)(() =>
                {
                    lab_Result.Text = "产品条码替换完成";
                }));
                Global.locket--;
                SuccessTest();

                // 重置替换状态
                oldBarcodeForReplacement = "";
            }
        }

        /// <summary>
        /// 获取旧记录及主键ID（根据产品类型）
        /// </summary>
        private async Task<(object record, int recordId, bool isNXP)> GetOldRecordWithId(string barcode)
        {
            if (Global.ProductName == "NXP金捷")
            {
                var record = await SqlHelper.sqliteDb.Queryable<AutoModel>()
                    .Where(it => it.case_code == barcode).FirstAsync();
                return (record, record?.Id ?? 0, true);  // 返回int类型ID（匹配SugarColumn定义）
            }
            else
            {
                var record = await SqlHelper.sqliteDb.Queryable<ManualModel>()
                    .Where(it => it.case_code == barcode).FirstAsync();
                return (record, record?.Id ?? 0, false);  // 返回int类型ID（匹配SugarColumn定义）
            }
        }

        /// <summary>
        /// 获取旧记录（根据产品类型）
        /// </summary>
        private async Task<(object record, bool isNXP)> GetOldRecord(string barcode)
        {
            if (Global.ProductName == "NXP金捷")
            {
                var record = await SqlHelper.sqliteDb.Queryable<AutoModel>()
                    .Where(it => it.case_code == barcode).FirstAsync();
                return (record, true);
            }
            else
            {
                var record = await SqlHelper.sqliteDb.Queryable<ManualModel>()
                    .Where(it => it.case_code == barcode).FirstAsync();
                return (record, false);
            }
        }

        /// <summary>
        /// 检查条码是否存在（根据产品类型）
        /// </summary>
        private async Task<bool> IsBarcodeExists(string barcode, bool isNXP)
        {
            return isNXP
                ? await SqlHelper.sqliteDb.Queryable<AutoModel>().Where(it => it.case_code == barcode).AnyAsync()
                : await SqlHelper.sqliteDb.Queryable<ManualModel>().Where(it => it.case_code == barcode).AnyAsync();
        }

        /// <summary>
        /// 更新记录条码（根据产品类型）
        /// </summary>
        private bool UpdateRecordWithNewBarcode(object record, string newBarcode, bool isNXP)
        {
            if (isNXP && record is AutoModel autoModel)
            {
                autoModel.case_code = newBarcode;
                autoModel.Whether_rework = true;
                return true;
            }
            else if (!isNXP && record is ManualModel manualModel)
            {
                manualModel.case_code = newBarcode;
                manualModel.Whether_rework = true;
                return true;
            }
            return false;
        }
        #endregion

        #region 产品特定处理
        /// <summary>
        /// 处理NXP金捷产品生产
        /// </summary>
        private async Task ProcessNXPProduction(string barcode, WeighTest weighData, TagTest tag)
        {
            // 检查重复条码
            if (await IsBarcodeExists(barcode, true))
            {
                throw new Exception($"校验失败：重复条码'{barcode}'");
            }

            // 获取产品信息
            var info = await SqlHelper.PostgreDb.Queryable<produceModelAfter>()
                .Where(it => it.production_feedback_id == barcode)
                .FirstAsync();

            if (info == null)
            {
                throw new Exception($"未找到条码'{barcode}'对应的产品信息");
            }

            // 保存数据
            var ccount = _currentNumber.ToString("D7");
            var dataToSave = new AutoModel
            {
                case_code = barcode,
                serial_number = $"98725{ccount}",
                outer_code = "",
                medium_code = "",
                Whether_rework = false
            };
            _currentNumber++;

            long insertResult = await SqlHelper.sqliteDb.Insertable(dataToSave).ExecuteCommandAsync();
            if (insertResult <= 0)
            {
                throw new Exception($"数据保存失败，条码：{barcode}");
            }

            // 激光烧录
            await ExecuteLaserBurn();
            SuccessTest();

            // 称重（正常模式执行）
            await PerformWeighing(weighData);

            // 满箱检测
            await CheckFullBox(weighData, tag, true);
        }

        /// <summary>
        /// 处理其他产品生产
        /// </summary>
        private async Task ProcessOtherProduction(string barcode, WeighTest weighData, TagTest tag)
        {
            // 检查重复条码
            if (await IsBarcodeExists(barcode, false))
            {
                throw new Exception($"校验失败：重复条码'{barcode}'");
            }

            // 保存数据
            var dataToSave = new ManualModel
            {
                case_code = barcode,
                medium_code = "",
                Whether_rework = false
            };

            long insertResult = await SqlHelper.sqliteDb.Insertable(dataToSave).ExecuteCommandAsync();
            if (insertResult <= 0)
            {
                throw new Exception($"数据保存失败，条码：{barcode}");
            }
            // 激光烧录
            await ExecuteLaserBurn();
            SuccessTest();

            // 称重（正常模式执行）
            await PerformWeighing(weighData);

            // 满箱检测
            await CheckFullBox(weighData, tag, false);
        }
        #endregion

        #region 称重与计数处理
        /// <summary>
        /// 执行称重操作
        /// </summary>
        private async Task PerformWeighing(WeighTest weighData)
        {
            var weight = weighData.Weigh();
            this.Invoke((Action)(() =>
            {
                lab_weight.Text = weight.ToString();
            }));
        }

        /// <summary>
        /// 检查满箱并处理
        /// </summary>
        private async Task CheckFullBox(WeighTest weighData, TagTest tag, bool isNXP)
        {
            // 返工模式下不执行称重相关逻辑
            if (chk_Rework.Checked)
                return;

            if (Global.locket == Global.MediumCount)
            {
                this.Invoke((Action)(() =>
                {
                    lab_Result.Text = "5秒后即将称重";
                }));
                await Task.Delay(5000);

                var currentWeight = weighData.Weigh();
                if (currentWeight > Global.Weigh)
                {
                    // 生成标签
                    await GenerateMediumLabel(tag, isNXP);

                    // 更新计数
                    Global.Medium++;
                    UpdateCountersUI();
                }
                else
                {
                    // 称重失败，删除最后一条记录
                    await DeleteLastRecord(isNXP);

                    this.Invoke((Action)(() =>
                    {
                        Global.locket--;
                        m_ini.IniWriteValue("locket", "locket", Global.locket);
                        lab_locket.Text = Global.locket.ToString();
                    }));
                    throw new Exception($"称重失败：当前重量不足:{currentWeight}'");
                }
            }

            // 外箱计数逻辑
            if (Global.Medium == Global.OuterCount)
            {
                await GenerateOuterLabel(tag, isNXP);
                UpdateOuterCounterUI();
            }
        }

        /// <summary>
        /// 生成中间标签
        /// </summary>
        private async Task GenerateMediumLabel(TagTest tag, bool isNXP)
        {
            if (isNXP)
            {
                var locketNumber = Serial10000Generator.NextSerialA();
                string prefix = $"SM2{DateTime.Now:yy}{locketNumber}";
                var mediumNumber = Serial10000Generator.NextSerialB();
                string mediumCode = $"SM2{DateTime.Now:yy}{mediumNumber}";
                tag.iSmal128lCode(mediumCode);
                tag.BarcodeMTAG(prefix, mediumCode);
                await SqlHelper.sqliteDb.Insertable(new MediumModel { medium_code = mediumCode, outer_code = "" }).ExecuteCommandAsync();
            }
            else
            {
                var locketNumber = SerialGenerator.NextSerialA();
                string prefix = $"{Global.ProductName} S{DateTime.Now:yyMMdd}{locketNumber}";
                var code = await tag.QrManualCode(prefix);
                var mediumNumber = SerialGenerator.NextSerialB();
                string mediumCode = $"S{DateTime.Now:yyMMdd}{mediumNumber}";
                tag.iSmallCode(mediumCode);
                tag.QrTAG(code, mediumCode);
                await SqlHelper.sqliteDb.Insertable(new MediumModel { medium_code = mediumCode, outer_code = "" }).ExecuteCommandAsync();
            }
        }

        /// <summary>
        /// 生成外箱标签 - 修复outerCode未定义问题
        /// </summary>
        private async Task GenerateOuterLabel(TagTest tag, bool isNXP)
        {
            Global.Medium = 0;
            string outerCode = ""; // 声明outerCode变量

            if (isNXP)
            {
                var outerNumber = Serial10000Generator.NextSerialC();
                outerCode = $"SM3{DateTime.Now:yy}{outerNumber}"; // 赋值而非重新定义
                tag.iOut128Code(outerCode);
                tag.BarcodeDataMTAG(outerCode, outerCode);
                await Task.Delay(200);
                tag.BarcodeDataMTAG(outerCode, outerCode);
            }
            else
            {
                var outerNumber = SerialGenerator.NextSerialC();
                var code = await tag.QrMediumCode();
                outerCode = $"M{DateTime.Now:yyMMdd}{outerNumber}"; // 赋值而非重新定义
                tag.iOutCode(outerCode);
                tag.QrMTAG(code, outerCode);
                await Task.Delay(200);
                tag.QrMTAG(code, outerCode);
            }

            // 现在outerCode在方法范围内有效
            await SqlHelper.sqliteDb.Insertable(new OuterModel { outer_code = outerCode }).ExecuteCommandAsync();
        }

        /// <summary>
        /// 更新计数器UI
        /// </summary>
        private void UpdateCountersUI()
        {
            this.Invoke((Action)(() =>
            {
                Global.locket = 0;
                m_ini.IniWriteValue("locket", "locket", Global.locket);
                lab_locket.Text = Global.locket.ToString();
                m_ini.IniWriteValue("Medium", "Medium", Global.Medium);
                lab_medium.Text = Global.Medium.ToString();
            }));
        }

        /// <summary>
        /// 更新外箱计数器UI
        /// </summary>
        private void UpdateOuterCounterUI()
        {
            this.Invoke((Action)(() =>
            {
                Global.Outer++;
                lab_medium.Text = Global.Medium.ToString();
                m_ini.IniWriteValue("Medium", "Medium", Global.Medium);
                m_ini.IniWriteValue("Outer", "Outer", Global.Outer);
                lab_out.Text = Global.Outer.ToString();
            }));
        }

        /// <summary>
        /// 删除最后一条记录
        /// </summary>
        private async Task DeleteLastRecord(bool isNXP)
        {
            if (isNXP)
            {
                var latestId = await SqlHelper.sqliteDb.Queryable<AutoModel>()
                    .OrderByDescending(it => it.create_time)
                    .Take(1)
                    .Select(it => it.Id)
                    .FirstAsync();

                if (latestId != null)
                {
                    await SqlHelper.sqliteDb.Deleteable<AutoModel>()
                        .Where(it => it.Id == latestId)
                        .ExecuteCommandAsync();
                }
            }
            else
            {
                var latestId = await SqlHelper.sqliteDb.Queryable<ManualModel>()
                    .OrderByDescending(it => it.create_time)
                    .Take(1)
                    .Select(it => it.Id)
                    .FirstAsync();

                if (latestId != null)
                {
                    await SqlHelper.sqliteDb.Deleteable<ManualModel>()
                        .Where(it => it.Id == latestId)
                        .ExecuteCommandAsync();
                }
            }
        }










        #endregion

        private async void button3_Click(object sender, EventArgs e)
        {
          
            try
            {
                // 开始异步事务

                // 目标时间
                DateTime targetTime = new DateTime(2025, 9, 12, 17, 57, 37, 84);

                // 1. 批量查询符合条件的Manual记录（只获取必要字段）
                var manualList = await SqlHelper.sqliteDb.Queryable<ManualModel>()
                    .Where(m => m.create_time <= targetTime && m.case_code.Contains("468"))
                    .Select(m => new { m.Id, m.medium_code }) // 仅选择需要的字段
                    .ToListAsync();

                if (manualList == null || !manualList.Any())
                {
                    Console.WriteLine("未找到符合条件的记录");
                    return;
                }

                Console.WriteLine($"共找到 {manualList.Count} 条符合条件的记录，开始批量处理...");

                // 2. 提取所有关联的medium_code（去重，减少查询次数）
                var mediumCodes = manualList
                    .Select(m => m.medium_code)
                    .Distinct()
                    .Where(code => !string.IsNullOrEmpty(code))
                    .ToList();

                if (mediumCodes.Any())
                {
                    // 3. 批量查询关联的Medium记录（只获取必要字段）
                    var mediumList = await SqlHelper.sqliteDb.Queryable<MediumModel>()
                        .Where(me => mediumCodes.Contains(me.medium_code))
                        .Select(me => new { me.Id, me.outer_code }) // 仅选择需要的字段
                        .ToListAsync();

                    if (mediumList.Any())
                    {
                        // 4. 提取所有关联的outer_code（去重）
                        var outerCodes = mediumList
                            .Select(me => me.outer_code)
                            .Distinct()
                            .Where(code => !string.IsNullOrEmpty(code))
                            .ToList();

                        // 5. 批量删除Outer表数据
                        if (outerCodes.Any())
                        {
                            int outerDeleted = await SqlHelper.sqliteDb.Deleteable<OuterModel>()
                                .Where(o => outerCodes.Contains(o.outer_code))
                                .ExecuteCommandAsync();
                            Console.WriteLine($"批量删除Outer记录：{outerDeleted} 条");
                        }

                        // 6. 批量删除Medium表数据
                        var mediumIds = mediumList.Select(me => me.Id).ToList();
                        int mediumDeleted = await SqlHelper.sqliteDb.Deleteable<MediumModel>()
                            .Where(me => mediumIds.Contains(me.Id))
                            .ExecuteCommandAsync();
                        Console.WriteLine($"批量删除Medium记录：{mediumDeleted} 条");
                    }
                }

                // 7. 批量删除Manual表数据
                var manualIds = manualList.Select(m => m.Id).ToList();
                int manualDeleted = await SqlHelper.sqliteDb.Deleteable<ManualModel>()
                    .Where(m => manualIds.Contains(m.Id))
                    .ExecuteCommandAsync();
                Console.WriteLine($"批量删除Manual记录：{manualDeleted} 条");

                // 异步提交事务
                await SqlHelper.sqliteDb.Ado.CommitTranAsync();
                Console.WriteLine("所有关联数据批量删除完成");
            }
            catch (Exception ex)
            {
                // 发生异常时异步回滚事务
                await SqlHelper.sqliteDb.Ado.RollbackTranAsync();
                Console.WriteLine($"删除过程中发生错误: {ex.Message}");
                throw;
            }
          
        }
    }
}
